package handler

import (
	"context"

	"github.com/micro/go-micro/v2/client"
	log "github.com/micro/go-micro/v2/logger"

	wallet "github.com/xionglongjun/welfare/wallet/srv/proto/wallet"

	user "github.com/xionglongjun/welfare/user/srv/proto/user"
)

type Wallet struct{}

// Call is a single request handler called via client.Call or the generated client code
func (e *Wallet) Call(ctx context.Context, req *wallet.Request, rsp *wallet.Response) error {
	userClient := user.NewUserService("go.micro.srv.user", client.DefaultClient)
	userClient.Call(ctx, &user.Request{})
	log.Info("Received Wallet.Call request")
	rsp.Msg = "Hello " + req.Name
	return nil
}

// Stream is a server side stream handler called via client.Stream or the generated client code
func (e *Wallet) Stream(ctx context.Context, req *wallet.StreamingRequest, stream wallet.Wallet_StreamStream) error {
	log.Infof("Received Wallet.Stream request with count: %d", req.Count)

	for i := 0; i < int(req.Count); i++ {
		log.Infof("Responding: %d", i)
		if err := stream.Send(&wallet.StreamingResponse{
			Count: int64(i),
		}); err != nil {
			return err
		}
	}

	return nil
}

// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
func (e *Wallet) PingPong(ctx context.Context, stream wallet.Wallet_PingPongStream) error {
	for {
		req, err := stream.Recv()
		if err != nil {
			return err
		}
		log.Infof("Got ping %v", req.Stroke)
		if err := stream.Send(&wallet.Pong{Stroke: req.Stroke}); err != nil {
			return err
		}
	}
}
